#include "stdafx.h"
#include "ogrewidget.h"
#include <QtCore/QTimer>
#include "GraphicsSystem.h"
#include "GameStateMain.h"
#include "BasicObject.h"
#include <OgreSceneManager.h>
#include <QtGui\QMouseEvent>

OgreWidget::OgreWidget(QWidget *pTop, QWidget *parent)
	: QWidget(parent),
	m_pTop(pTop)
{
	m_isNeedRender = true;
	setFocusPolicy(Qt::StrongFocus);
	m_isInit = false;
	ui.setupUi(this);
	Init();
}

OgreWidget::~OgreWidget()
{

}

QPaintEngine* OgreWidget::paintEngine() const
{
	return NULL;
}

void OgreWidget::RemoveNodeData(const ZMString&strNodeName)
{
	m_pGameState->RemoveNodeData(strNodeName);
}
void OgreWidget::ChangeObjMaterial(const ZMVector<ZMString>& vObjName, const ZMString& materialName)
{
	m_pGameState->ChangeObjMaterial(vObjName, materialName);

}

void OgreWidget::ChangeMaterial(bool isWire)
{
	if (!isWire)	m_pGameState->changeMaterialToPolyon();
	else m_pGameState->changeMaterialToWire();
}
void OgreWidget::AddMeshData(const ZMString&parentNodeName, const ZMString&strNodeName, const ZMString&strMatName, const MeshData& data)
{
	m_pGameState->AddObjectToNode(parentNodeName, strNodeName, data.GetMeshName(), strMatName, data);
}
void OgreWidget::CreateOrGetNode(const Ogre::String&strParentNodeName, const Ogre::String&strNodeName)
{
	m_pGameState->CreateOrGetNode(strParentNodeName, strNodeName);
}

void OgreWidget::SetCamera(const ZMPoint3D& position, const ZMPoint3D& look)
{
	m_pGameState->SetCameraPos(Ogre::Vector3(position[0], position[1], position[2]), Ogre::Vector3(look[0], look[1], look[2]));
}

void OgreWidget::BindRoadMileLine(SharedPointer<RoadMileLine> pMile)
{
	m_pGameState->BindRoadMileLine(pMile);

}

void OgreWidget::OffsetObj(const ZMString& objName, const ZMPoint3D& offsetAxis, const ZMReal& fOffsetValue, bool isAbs)
{
	m_pGameState->OffsetObj(objName, offsetAxis, fOffsetValue, isAbs);
}

void OgreWidget::RotateObj(const ZMString& objName, const ZMPoint3D& pntOrign, const ZMPoint3D& rAxis, const ZMReal& fAngle, bool isAbs)
{
	m_pGameState->RotateObj(objName, pntOrign, rAxis, fAngle, isAbs);

}

void OgreWidget::paintEvent(QPaintEvent *)
{
	//if (!m_isInit)Init();
	if (updatesEnabled())
	{
		Render();
	}
}

void OgreWidget::Init()
{
	m_isInit = true;

	setAttribute(Qt::WA_PaintOnScreen, true);
	m_pGameState = boost::shared_ptr<OgreModel::GameStateMain>(new OgreModel::GameStateMain("just test"));
	m_pGraphicsSystem = boost::shared_ptr<OgreModel::GraphicsSystem>(new OgreModel::GraphicsSystem(m_pGameState.get()));
	m_pGameState->_notifyGraphicsSystem(m_pGraphicsSystem.get());

	QWidget* pTopWin = (QWidget*)parent();
	if (pTopWin == NULL) pTopWin = this;
 	while (pTopWin->parent())
	{
		pTopWin = (QWidget*)pTopWin->parent();
	}
	m_pGraphicsSystem->initialize(pTopWin, this);

	m_pGraphicsSystem->createScene01();
	m_pGraphicsSystem->createScene02();
	m_startTime = m_Timer.getMicroseconds();

	//QTimer *timer = new QTimer(this);
	//connect(timer, SIGNAL(timeout()), this, SLOT(Render()));
	//timer->start(20);
}

void OgreWidget::mouseDoubleClickEvent(QMouseEvent* event)
{
	QPoint  mousePos = event->pos();
	ZMString strObjName = m_pGraphicsSystem->GelSelObjName(mousePos.x() / (float)width(), mousePos.y() / (float)height());

	{
		emit signSelChange(strObjName);
	}
}

bool OgreWidget::event(QEvent *event)
{
	switch (event->type())
	{
	case QEvent::UpdateRequest:
		//if (updatesEnabled())
		{
			Render();
		}
		return true;

	default:
		return QWidget::event(event);
	}
}

void OgreWidget::Render()
{
	if (m_isNeedRender)
	{
		m_isNeedRender = false;
		unsigned long endTime = m_Timer.getMicroseconds();
		double timeSinceLast = 1.0 / 60.0;
		timeSinceLast = (endTime - m_startTime) / 1000000.0;
		timeSinceLast = std::min(1.0, timeSinceLast); //Prevent from going haywire.
		m_startTime = endTime;
		m_pGraphicsSystem->beginFrameParallel();
		m_pGraphicsSystem->update(static_cast<float>(timeSinceLast));
		m_pGraphicsSystem->finishFrameParallel();
		m_pGraphicsSystem->finishFrame();
		m_isNeedRender = true;
		QApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
	}

}